#pragma once
#import <msxml3.dll>
#include <vector>
#include "Renderable2D.h"
#include "SpriteTile.h"

using namespace std;

namespace Graphics
{
	enum ANI_STATE
	{
		ANI_STOP,
		ANI_PLAYING,
	};
	class Animation :public Renderable2D
	{
	public:
		// store one image in a frame
		struct Image
		{
			int texture_id;
			int tile_id;
			int x;
			int y;

			Image(void);
			Image(const MSXML2::IXMLDOMNodePtr& pNode);
			bool LoadXML(const MSXML2::IXMLDOMNodePtr& pNode);
		};
		
		// store one frame in a animation
		struct Frame
		{
			vector<Image*> images;
			int delay;
			Frame(const MSXML2::IXMLDOMNodePtr& pNode);
			~Frame(void);
			bool LoadXML(const MSXML2::IXMLDOMNodePtr& pNode);
		};
		
	private:
		// store one texture in a animation
		class AniTexture:public SpriteTile
		{
			SpriteTile::TileData m_Data;
			Position m_Pos;

		public:
			AniTexture(DWORD col,DWORD row,Drawable* image);
			~AniTexture(void);
			
			// set which tile will be render
			void SetIndex(DWORD i);

			// set the position of sprite
			void SetPos(int x, int y);
			virtual const Position& GetPos(void);

			virtual const SpriteTile::TileData& GetData(void);
		};



		// description of the animation
		std::string m_Description;
		
		// store frames infomation
		vector<Frame*> m_Frames;

		// store animations infomation
		vector<AniTexture*> m_Textures;

		bool m_IsPlaying;
		Frame* m_pFrame;
		int m_Delay;
		int m_NowFrame;

		// speed of playback
		float m_Speed;

		// state of animation
		ANI_STATE m_State;

        // id offset for each animation
        int m_OffsetID;
	public:
		Animation(void);
		virtual ~Animation(void);

		bool LoadTextureXML(const MSXML2::IXMLDOMNodePtr& pNode);
		bool LoadXML(const MSXML2::IXMLDOMNodePtr& pNode);
		bool Load(std::string filename);
		
		ANI_STATE Play(void);
		ANI_STATE Stop(void);

		virtual bool RenderImpl(void);

        virtual void SetViewport(Viewport* viewport);

		bool SetFrame(int frame);

		ANI_STATE GetState(void);

		float GetSpeed(void);
		void SetSpeed(float speed);

		const std::string& GetDescription(void);

        int GetOffsetID() const {return m_OffsetID;}
        void SetOffsetID(int offsetID) {m_OffsetID = offsetID;}

	};
}